<template>
  <Card :style="isMobile ? 'width: 100%;margin: 0 auto' : 'width: 50%;margin: 0 auto'">
    <template #title>一位神秘的懒鬼分享了脚本： {{ formState.name }}</template>
    <template #content>
      <form @submit.prevent='onSubmit'>
        <div class="formgroup-inline align-items-center grid grid-cols-4 gap-4">
          <div v-for="(item, index) in formState.args" class="mt-5 mb-5">
            <label :for="item.id" class="text-sm font-semibold leading-6 text-gray-900">{{ item.name }}</label>
            <div class="flex flex-column mt-2">
              <InputText v-if="item.type === 'one_str'" :id="item.id" v-model="item.value" class="w-full"
                         autocomplete="off"/>

              <Textarea v-else-if="item.type === 'multi_str'" :id="item.id" v-model="item.value" rows="5"
                        cols="50"
                        autocomplete="off"/>

              <div v-else-if="item.type === 'bool'" class="flex flex-wrap gap-3">
                <div class="flex align-items-center">
                  <RadioButton v-model="item.value" inputId="ingredient1" name="pizza"
                               :value="true" :id="item.id"/>
                  <label for="ingredient1" class="ml-2">是</label>
                </div>
                <div class="flex align-items-center">
                  <RadioButton v-model="item.value" inputId="ingredient2" name="pizza" :value="false"
                               :id="item.id"/>
                  <label for="ingredient1" class="ml-2">否</label>
                </div>
              </div>

              <div v-else-if="item.type === 'enums'" class="flex flex-wrap gap-3">
                <Select class='w-8rem' v-model="item.value" :options="item.enums"
                        aria-labelledby="basic"/>
              </div>
              <div v-else-if="item.type === 'password'" class="flex flex-wrap gap-3">
                <Password v-model="item.value" :feedback="false"/>
              </div>
              <div v-else-if="item.type === 'number'" class="flex flex-wrap gap-3">
                <InputNumber v-model="item.value"/>
              </div>
              <div v-else-if="item.type === 'image'" class="flex flex-wrap gap-3">

                <FileUpload v-if="!src" @select="onFileSelect" accept="image/*" customUpload
                            :pt="{content:{style: {'display': 'none'}}, header:{style: {'padding': '0', 'border': '0'}}}">
                  <template #header="{ chooseCallback, uploadCallback, clearCallback, files }">
                    <Button @click="chooseCallback()" icon="pi pi-image" text
                            severity="secondary"></Button>
                  </template>
                </FileUpload>
                <img v-if="src" :src="src" alt="Image" class="shadow-md rounded-xl w-24"
                     style="filter: grayscale(100%)"/>
              </div>
              <small class="p-error">
                {{ errors[item.id] }}
              </small>
            </div>
          </div>
        </div>

        <div style="width:100%;display: flex; " class='mb-3'>
          <Button type="submit" label="运行" :loading="debugLoading"/>
          <Button key="back" danger @click="() => discontinue()" severity="secondary" class='ml-2'>终止</Button>
          <Button @click="copyContent" severity="secondary" class='ml-2'>复制</Button>
        </div>
      </form>
      <div ref="xtermContainer"/>
    </template>
  </Card>
</template>
<script setup>
import {ref, defineExpose, reactive, watch} from "vue";
import {useRequest} from 'ahooks-vue';
import {ApiDiscontinue, ApiGetShare} from "@/api/toolkit.js";
import 'xterm/css/xterm.css'
import {Terminal} from 'xterm';
import {FitAddon} from 'xterm-addon-fit'
import useClipboard from 'vue-clipboard3'
import {useRoute} from "vue-router";
import Select from "primevue/select";

const isMobile = ref(window.innerWidth < 768);
const {toClipboard} = useClipboard()

defineExpose({
  show: (index) => {
    visible.runModal = true;
    run({id: index})
  },
  setContent: (content) => {
    newContent.value = content
  }
})

const route = useRoute();
const share_id = route.query.share_id
const xtermContainer = ref()

const term = ref()
const refForm = ref()
const argsSelectIndex = ref(-1);
const visible = reactive({
  runModal: false,
  valueModal: false,
  setArgsFile: false
})
const newContent = ref()
const formState = ref({})
const debugLoading = ref(false)
const showValue = ref({
  index: 0,
  value: ''
})


watch(xtermContainer, (newValue) => {
  if (newValue !== undefined && newValue !== null) {
    term.value = new Terminal({
      fontSize: 14,
      convertEol: false, // 启用时，光标将设置为下一行的开头
      rendererType: 'canvas', // 渲染类型
      cursorBlink: false, // 光标闪烁
      theme: {
        background: '#060101', // 背景色
        cursor: 'help' // 设置光标
      },
      scrollback: 10000,
    })
    const fitAddon = new FitAddon();
    term.value.loadAddon(fitAddon);
    term.value.open(xtermContainer.value)
    fitAddon.fit();


  }
})

// API
const {data, loading, run} = useRequest(ApiGetShare, {
  manual: false,
  defaultParams: [{
    share_id: share_id,
  }],
  params: {share_id: share_id},
  onSuccess: e => {
    formState.value = e.data.detail
  },
})

const errors = ref({});
let pid = ''


const onSubmit = async () => {
  const values = {}
  if (formState.value.args) {
    let is_exit = false
    formState.value.args.forEach(item => {
      console.log(item.value)
      if (item.require && (item.value === '' || item.value === undefined || item.value === null)) {
        errors.value[item.id] = '该参数必填'
        is_exit = true
      } else {
        errors.value[item.id] = ''
        values[item.id] = item.value
      }
    })
    if (is_exit) {
      return
    }
  }

  debugLoading.value = true

  initSocket({share_id: formState.value.share_id})
}

function inputFull(index) {
  showValue.value.index = index
  showValue.value.value = formState.value.args[index]['default_value']
  visible.valueModal = true
}

function setInputValueFunc() {
  formState.value.args[showValue.value.index]['default_value'] = showValue.value.value
  visible.valueModal = false
}

function setSelectFile(path) {
  formState.value.args[argsSelectIndex.value]['default_value'] = path.join('/')
  visible.setArgsFile = false
}

const discontinue = async () => {
  const result = await ApiDiscontinue(pid)
  if (result.code === 0) {
    message.success(result.msg)
  } else {
    message.error(result.msg)
  }
}
const initSocket = (params) => {
  let isOk = false
  const protocol = document.location.protocol;
  console.log(protocol)
  let websocket_protocol = 'ws://'
  if (protocol === "https:") {
    websocket_protocol = 'wss://'

  }

  const socket = new WebSocket(websocket_protocol + window.location.host + '/ws/v1/share/start')
  term.value.clear()
  socket.onmessage = async e => {
    if (e.data instanceof Blob) {
      const text = await e.data.text();
      term.value.write(text);
    } else {
      try {
        const data = JSON.parse(e.data);
        if (data.end === true) {
          isOk = data.status
        } else if (data.end === false) {
          pid = data.pid
        }
      } catch (error) {
        // 如果不是 JSON 类型，则将其写入终端
        term.value.write(e.data);
      }
    }
  }


  socket.onopen = () => {
    socket.send(JSON.stringify(params))
    term.value.focus()
  }

  socket.onclose = e => {
    debugLoading.value = false
  }
  term.value.onKey(async data => {
    if (data.key === '\x03') {
      // 复制
      await toClipboard(term.value.getSelection())
    }
  })
}

const copyContent = async () => {
  term.value.selectAll()
  await toClipboard(term.value.getSelection())
}

</script>

<style>
.xterm-cursor {
  visibility: hidden;
}
</style>